package com.yst.gateway.monitor.common.validator.web;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.web.servlet.support.RequestContext;

/**
 * 后端校验和前端校验的转换，可扩展
 * @author sheungxin
 *
 */
public class FieldAnnotationFilter {
	private RequestContext requestContext;
	private List<String[]> fieldValidateList;
	private String groups;
	
	public FieldAnnotationFilter(RequestContext requestContext){
		this.requestContext=requestContext;
	}
	
	public List<String[]> filter(Field field,String groups){
		if(field!=null){
			this.fieldValidateList=new ArrayList<String[]>();
			this.groups=groups;
			for(Annotation annotation:field.getAnnotations()){
				if(annotation instanceof NotNull){
					filterNotNull(annotation);
				}else if(annotation instanceof NotBlank){
					filterNotBlank(annotation);
				}else if(annotation instanceof Email){
					filterEmail(annotation);
				}else if(annotation instanceof Length){
					filterLength(annotation);
				}else if(annotation instanceof Pattern){
					filterPattern(annotation);
				}else if(annotation instanceof Max){
					filterMax(annotation);
				}else if(annotation instanceof Min){
					filterMin(annotation);
				}
			}
		}
		return fieldValidateList;
	}
	
	private void filterNotNull(Annotation annotation){
		NotNull notNull=(NotNull) annotation;
        if(notNull!=null){
        	if(notNull.groups().length==0||inGroups(notNull.groups(), groups)){
        		String messageName=notNull.message();
                fieldValidateList.add(new String[]{"required","true",requestContext.getMessage(messageName.substring(1, messageName.length()-1))});
        	}
        }
	}
	
	private void filterNotBlank(Annotation annotation){
		NotBlank notEmpty=(NotBlank)annotation;
        if(notEmpty!=null){
        	if(notEmpty.groups().length==0||inGroups(notEmpty.groups(), groups)){
        		String messageName=notEmpty.message();
                fieldValidateList.add(new String[]{"required","true",requestContext.getMessage(messageName.substring(1, messageName.length()-1))});
        	}
        }
	}
	
	private void filterEmail(Annotation annotation){
		 Email email=(Email)annotation;
         if(email!=null){
        	if(email.groups().length==0||inGroups(email.groups(), groups)){
        		String messageName=email.message();
            	fieldValidateList.add(new String[]{"email","true",requestContext.getMessage(messageName.substring(1, messageName.length()-1))});
         	}
         }
	}
	
	private void filterMax(Annotation annotation){
		Max max=(Max)annotation;
        if(max!=null){
        	if(max.groups().length==0||inGroups(max.groups(), groups)){
        		fieldValidateList.add(new String[]{"max",max.value()+"",requestContext.getMessage("model.field.num.max").replace("{1}", max.value()+"")});
        	}
        }
	}
	
	private void filterMin(Annotation annotation){
		Min min=(Min)annotation;
        if(min!=null){
        	if(min.groups().length==0||inGroups(min.groups(), groups)){
        		fieldValidateList.add(new String[]{"min",min.value()+"",requestContext.getMessage("model.field.num.min").replace("{0}", min.value()+"")});
        	}
        }
	}
	private void filterLength(Annotation annotation){
		Length length=(Length)annotation;
        if(length!=null){
        	if(length.groups().length==0||inGroups(length.groups(), groups)){
        		if(length.max()==-1){
        			fieldValidateList.add(new String[]{"minlength",length.min()+"",requestContext.getMessage(
                    		"model.field.min.length").replace("{0}", length.min()+"")});
        		}else if(length.min()==0){
        			fieldValidateList.add(new String[]{"maxlength",length.max()+"",requestContext.getMessage(
            			"model.field.max.length").replace("{1}", length.max()+"")});
        		}else{
        			fieldValidateList.add(new String[]{"rangelength","["+length.min()+","+length.max()+"]",requestContext.getMessage(
                    	"model.field.range.length")
                    	.replace("{0}", length.min()+"")
                    	.replace("{1}", length.max()+"")});
        		}
        	}
        }
	}
	
	private void filterPattern(Annotation annotation){
		Pattern pattern=(Pattern)annotation;
        if(pattern!=null){
        	if(pattern.groups().length==0||inGroups(pattern.groups(), groups)){
        		String messageName=pattern.message();
                fieldValidateList.add(new String[]{"regex","'"+pattern.regexp()+"'",requestContext.getMessage(messageName.substring(1, messageName.length()-1))});
        	}
        }
	}
	
	@SuppressWarnings("rawtypes")
	private boolean inGroups(Class[] classes,String specified){
		boolean flag=false;
		if(StringUtils.isNotBlank(specified)){
			for(Class cl:classes){
				if(specified.contains(cl.getSimpleName())){
					flag=true;
					break;
				}
			}
		}
		return flag;
	}
}
